declare boundary-space strip;
import module namespace
    jj = "http://kumquat.emse.fr/utilitaires"
    at "jjutils.xq" ;
    
declare function local:header($item as element()) as node()* {
	(
	attribute user {jj:get-info($item,"user")}, 
	attribute room {"Hall"},
  	jj:get-info($item,"time")
	)
};

declare function local:get-xy($item as element(),$id as xs:string) as xs:integer* {
	let $prev := $item/preceding-sibling::item
		[jj:get-info(.,"type") = ("create box","move box")]
		[(jj:get-info(.,"boxid"),jj:get-info(.,"contributionid"))=$id][1]
	return (xs:integer(jj:get-info($prev,"x")),xs:integer(jj:get-info($prev,"y")))	
};

declare function local:create-position($x as xs:string, $y as xs:string) as element() {
	<position>{attribute x {((xs:integer($x)+400) * 2) idiv 3},
  			   attribute y {((xs:integer($y)+300) * 2) idiv 3}}</position>
};

declare function local:create-move($item as element(), 
									$id as xs:string, 
									$x as xs:integer, $y as xs:integer) as element() {
		<event>{local:header($item), (: put in position :)
  		<grapheur>{ 		
  			<argument>{
  				attribute id {$id},
  				local:create-position($x,$y)
  			}</argument>
  		}</grapheur>
  		}</event>							
};	

declare function local:create-average-move($item as element(),
										   $id as xs:string,
										   $p1 as xs:integer*,
										   $p2 as xs:integer*) as element() {
		let $x_ := xs:string(($p1[1]+$p2[1]) idiv 2)
  		let $y_ := xs:string(($p1[2]+$p2[2]) idiv 2)
  		return		
			local:create-move($item,$id,$x_,$y_)						   
};	

declare function local:create-delete($item as element(), $id as xs:string) as element()	{
		<event>{local:header($item), (: delete  :)
  		<grapheur>{ 		
  			<argument>{
  				attribute id {$id},
  				attribute action {"delete"}
  			}</argument>
  		}</grapheur>
  		}</event>
};	

declare function local:is-deleted-arrow($item as element(), $id as xs:string) as xs:boolean {
		let $lastop := $item/preceding-sibling::item
  			[jj:get-info(.,"type")=("create arrow","delete arrow")]
  			[(jj:get-info(.,"arrowid"),jj:get-info(.,"contributionid"))=$id][1]
  		return (jj:get-info($lastop,"type")="delete arrow")	
};

declare function local:is-deleted-box($item as element(), $id as xs:string) as xs:boolean {
  		fn:not(fn:empty($item/preceding-sibling::item
  			[jj:get-info(.,"type")="delete box"]
  			[jj:get-info(.,"contributionid")=$id][1]))	
};						   								 

let $t := $arguments[1]
let $doc := doc($t)
let $type := if ($arguments[2]) then xs:string($arguments[2]) else "text"
let $showtext := $type=("text","textid")
let $showid := $type=("id","textid") 
for $item in $doc/display/item
let $type := jj:get-info($item,"type")
let $x := jj:get-info($item,"x")
let $y := jj:get-info($item,"y")
let $contributionid := jj:get-info($item,"contributionid")
let $objectid := (jj:get-info($item,"boxid"),jj:get-info($item,"arrowid"))
return
	if ($type="create box") then
  		(<event>{local:header($item), (: create :)
  		<grapheur>{ 		
  			<argument>{
  				attribute id {$objectid},
  				attribute action {"create"},
  				attribute type {"box"}
  			}</argument>
  		}</grapheur>
  		}</event>,
		<event>{local:header($item), (: add name :)
  		<grapheur>{
  			<argument>{
  				attribute id {$objectid},
  				<name><text lang="fr">{
  					if ($showid) then ("<",$objectid,">") else (),
  					if ($showtext) then jj:get-info($item,"title") else ()
  				}</text></name>
  			}</argument>
  		}</grapheur>
  		}</event>,
  		<event>{local:header($item), (: add comment :)
  		<grapheur>{
  			<argument>{
  				attribute id {$objectid},
  				<comment><text lang="fr">{if ($showtext) then jj:get-info($item,"comment") else jj:get-info($item,"title")}</text></comment>
  			}</argument>
  		}</grapheur>
  		}</event>,
  		local:create-move($item,$objectid,$x,$y)
  		)
  	else if ($type="move box") then
  		(local:create-move($item,$contributionid,$x,$y),
  		for $arrow in $item/preceding-sibling::item
  			[jj:get-info(.,"type")="create arrow"]
  			[(jj:get-info(.,"sourceid"),jj:get-info(.,"targetid")) = $contributionid] (:HANDLE RECONNECTS and DELETES:)
  		let $srcid := jj:get-info($arrow,"sourceid")
  		let $targid := jj:get-info($arrow,"targetid")
  		let	$otherid := if ($srcid = $contributionid) then $targid else $srcid 
  		let $arrowid := jj:get-info($arrow, "arrowid")
  		let $createbend := fn:count($item/preceding-sibling::item
  			[jj:get-info(.,"type")="create bend point"]
  			[jj:get-info(.,"contributionid")=$arrowid])
  		let $deletebend := fn:count($item/preceding-sibling::item
  			[jj:get-info(.,"type")="delete bend point"]
  			[jj:get-info(.,"contributionid")=$arrowid])
  		where fn:not(local:is-deleted-arrow($item, $arrowid)) and (: arrow still exists :)
  		     fn:not(local:is-deleted-box($item,$otherid)) and   (:other box still exists:)
  			($createbend le $deletebend) (: arrow doesn't have bendpoint :) 
  		return
  			let $otherpos := local:get-xy($item,$otherid)
  			return local:create-average-move($item,$arrowid,($x,$y),$otherpos)
  		)
  	else if ($type=("delete box")) then	
  		(local:create-delete($item,$contributionid), (: delete :)
  		for $arrow in $item/preceding-sibling::item
  			[jj:get-info(.,"type")="create arrow"] (:HANDLE RECONNECTS and DELETES:)
  			[(jj:get-info(.,"sourceid"),jj:get-info(.,"targetid")) = $contributionid]
  		let $arrowid := jj:get-info($arrow, "arrowid")
  		where fn:not(local:is-deleted-arrow($item, $arrowid)) (: arrow still exists :)
  		return
			local:create-delete($item,$arrowid)
  		)  		
  	else if ($type="edit box") then
  		<event>{local:header($item), (: add name :)
  		<grapheur>{
  			<argument>{
  				attribute id {$contributionid},
  				element {if ($showtext) then "name" else "comment"} {<text lang="fr">{
  					if ($showid) then ("<",$contributionid,">") else (),
  					if ($showtext) then jj:get-info($item,"title") else ()
  				}</text>}
  			}</argument>
  		}</grapheur>
  		}</event>	
	else if ($type="add comment") then
		<event>{local:header($item), (: add comment :)
  		<grapheur>{
  			<argument>{
  				attribute id {$contributionid},
  				if ($showtext) then <comment><text lang="fr">{jj:get-info($item,"comment")}</text></comment> else ()
  			}</argument>
  		}</grapheur>
  		}</event>
  	else if ($type="create arrow") then	
  		(<event>{local:header($item), (: create the arrow:)
  		<grapheur>{ 		
  			<argument>{
  				attribute id {$objectid},
  				attribute action {"create"},
  				attribute type {"arrow"}
  			}</argument>
  		}</grapheur>
  		}</event>,
		<event>{local:header($item), (: add name :)
  		<grapheur>{
  			<argument>{
  				attribute id {$objectid},
  				<name><text lang="fr">{
  					if ($showid) then () (:"<",$objectid,">":) else ()
  				}</text></name>
  			}</argument>
  		}</grapheur>
  		}</event>,
  		<event>{local:header($item), (: add comment :)
  		<grapheur>{
  			<argument>{
  				attribute id {$objectid},
  				<comment><text lang="fr"></text></comment>
  			}</argument>
  		}</grapheur>
  		}</event>,  		
  		<event>{local:header($item), (: add src-rel :)
  		<grapheur>{
  			<relation>{
  				attribute action {"create"},
  				attribute from {jj:get-info($item,"sourceid")},
  				attribute to {$objectid}
  			}</relation>
  		}</grapheur>
  		}</event>,
  		<event>{local:header($item), (: add dest-rel :)
  		<grapheur>{
  			<relation>{
  				attribute action {"create"},
  				attribute from {$objectid},
  				attribute to {jj:get-info($item,"targetid")}
  			}</relation>
  		}</grapheur>
  		}</event>,
  		let $srcpos := local:get-xy($item,jj:get-info($item,"sourceid"))
  		let $targpos := local:get-xy($item,jj:get-info($item,"targetid"))
		return	
			local:create-average-move($item,$objectid,$srcpos,$targpos)
		)
  	else if ($type=("delete arrow")) then	
  		<event>{local:header($item), (: delete :)
  		<grapheur>{ 		
  			<argument>{
  				attribute id {$contributionid},
  				attribute action {"delete"}
  			}</argument>
  		}</grapheur>
  		}</event>			
	else if ($type="move bend point") then
		local:create-move($item,$contributionid,$x,$y)	
	else if ($type="delete bend point") then
		let $arrow := $item/preceding-sibling::item
			[jj:get-info(.,"type")="create arrow"] (:HANDLE RECONNECTS:)
			[jj:get-info(.,"arrowid")=$contributionid][1]
  		let $srcpos := local:get-xy($item,jj:get-info($arrow,"sourceid"))
  		let $targpos := local:get-xy($item,jj:get-info($arrow,"targetid"))
  		return local:create-average-move($item,jj:get-info($arrow,"arrowid"),$srcpos,$targpos)
	else
		()
